package com.chongqing.shiro.web.controller;


import com.chongqing.shiro.model.entity.Permission;
import com.chongqing.shiro.model.entity.Role;
import com.chongqing.shiro.model.entity.User;
import com.chongqing.shiro.model.vo.ResponseVo;
import com.chongqing.shiro.model.vo.ResultUtil;
import com.chongqing.shiro.service.PermissionService;
import com.chongqing.shiro.service.RoleService;
import com.chongqing.shiro.service.filter.MyShiroRealm;
import com.chongqing.shiro.util.CoreConst;
import com.chongqing.shiro.util.PageUtil;
import com.chongqing.shiro.web.vo.PageResultVo;
import com.chongqing.shiro.web.vo.PermissionTreeListVo;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.xml.transform.Result;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Description: -------------------
 * @Author: YangXingfu
 * @Date: 2019/01/23 11:07
 */


@Controller
@RequestMapping("/role")
public class RoleController {

    private static final Logger log = LoggerFactory.getLogger(RoleController.class);

    @Autowired
    private RoleService roleService;

    @Autowired
    private PermissionService permissionService;

    @Autowired
    private MyShiroRealm myShiroRealm;


    /**角色列表数据*/
    @PostMapping("/list")
    @ResponseBody
    public PageResultVo pageRoles(Role role, Integer limit, Integer offset) {
        try {
            PageHelper.startPage(PageUtil.getPageNo(limit, offset), limit);
            List<Role> roleList = roleService.selectRoles(role);
            PageInfo<Role> pages = new PageInfo<>(roleList);
            return ResultUtil.table(roleList, pages.getTotal());
        } catch (Exception e) {
            log.error(String.format("RoleController.loadRoles%s" + e));
            throw e;
        }
    }

    /**新增角色*/
    @PostMapping("/add")
    @ResponseBody
    public ResponseVo addRole(Role role) {
        try {
            int a = roleService.insert(role);
            if (a > 0) {
                return ResultUtil.success("添加角色成功");
            } else {
                return ResultUtil.error("添加角色失败");
            }

        } catch(Exception e) {
            log.error(String.format("RoleController.addRole%s", e));
            throw e;
        }
    }


    /**删除角色*/
    @GetMapping("/delete")
    @ResponseBody
    public ResponseVo deleteRole(String roleId) {
        if (roleService.findRoleId(roleId).size() > 0) {
            return ResultUtil.error("删除失败，该角色下存在用户");
        }
        List<String> roleIdsList = Arrays.asList(roleId);
        int a = roleService.updateStatusBatch(roleIdsList, CoreConst.STATUS_INVALID);
        if (a > 0) {
            return ResultUtil.success("删除角色成功");
        } else {
            return ResultUtil.error("删除角色失败");
        }

    }

    /**批量删除角色*/
    @GetMapping("/batch/delete")
    @ResponseBody
    public ResponseVo batchDeleteRole(String roleIdStr) {
        String[] roleIds = roleIdStr.split(",");
        List<String> roleIdsList = Arrays.asList(roleIds);
        if (roleService.findRoleIds(roleIdsList).size() > 0) {
            return ResultUtil.error("删除失败, 删除的角色下存在用户");
        }

        int a = roleService.updateStatusBatch(roleIdsList,  CoreConst.STATUS_INVALID);
        if (a > 0 ) {
            return ResultUtil.success("删除角色成功");
        } else {
            return ResultUtil.error("删除角色失败");
        }

    }

    /**编辑角色详情*/
    @GetMapping("/edit")
    public String detail(Model model, Integer id) {
        Role role = roleService.findById(id);
        model.addAttribute("role", role);
        return "role/detail";
    }

     /**编辑角色*/
     @PostMapping("/edit")
     @ResponseBody
     public ResponseVo editUser(@ModelAttribute("role")Role role) {
        int a = roleService.updateByRoleId(role);
        if (a > 0) {
            return ResultUtil.success("编辑角色成功");
        } else {
            return ResultUtil.error("编辑角色失败");
        }
     }

     /**分配权限列表查询*/
     @PostMapping("assign/permission/list")
     @ResponseBody
     public List<PermissionTreeListVo> assignRole(String roleId) {
         List<PermissionTreeListVo> listVos = new ArrayList<>();
         List<Permission> allPermissions = permissionService.selectAll((CoreConst.STATUS_VALID));
         List<Permission> hasPermissions = roleService.findPermissionByRoleId(roleId);
         for (Permission permission : allPermissions) {
             PermissionTreeListVo vo = new PermissionTreeListVo();
             vo.setId(permission.getId());
             vo.setPermissionId(permission.getPermissionId());
             vo.setName(permission.getName());
             vo.setParentId(permission.getParentId());
             for (Permission hasPermission : hasPermissions) {
                 if (hasPermission.getPermissionId().equals(permission.getPermissionId())) {
                     // 有权限则勾选
                     vo.setChecked(true);
                     break;
                 }
             }
             listVos.add(vo);
         }
         return listVos;
     }

     /**分配权限*/
     @PostMapping("/assign/permission")
    @ResponseBody
    public ResponseVo assignRole(String roleId, String permissionIdStr) {
         List<String> permissionIdList = new ArrayList<>();
         String[] permissionIds = permissionIdStr.split(",");
         permissionIdList = Arrays.asList(permissionIds);

         ResponseVo responseVo = roleService.addAssifnPermission(roleId, permissionIdList);
         /**重新加载角色下所有用户权限权限*/
         List<User> userList = roleService.findByRoleId(roleId);
         if (userList.size() > 0) {
             List<String> userIds = new ArrayList<>();
             for (User user : userList) {
                 userIds.add(user.getUserId());
             }
             myShiroRealm.clearAuthorizationByUserId(userIds);
         }
         return responseVo;
     }

}